// File typing implementation for Win32
// Copyright 2006 (C) Ralph Thomas

#include <model/file/typerWin32.h>
#include <windows.h>
#include <vector>

#define UNKNOWN_FILE	"x-mission/x-file"

namespace model {
	std::string getFileType( const boost::filesystem::path& p ) {
		//
		// We look for the registry key "HKEY_CLASSES_ROOT/.<ext>/Content Type".
		// This requires us to first get the file's extension. If it has no
		// extension then we can't type it.
		//
		std::string file( p.leaf() );
		std::string::size_type dot = file.rfind( "." );
		if( dot == std::string::npos ) return UNKNOWN_FILE;
		std::string ext( file.substr( dot ) );
		//
		// Open the key we want in the registry; if it doesn't exist then we
		// have to return the UNKNOWN_FILE type. It would be nice to use
		// RegGetKey for this, perhaps once Vista is released.
		//
		HKEY typeKey;
		if( RegOpenKeyEx( HKEY_CLASSES_ROOT, ext.c_str(), 0, KEY_READ, &typeKey ) )
			return UNKNOWN_FILE;
		//
		// Attempt to extract the size of the value of the "Content Type" key.
		//
		DWORD keyType = 0;
		DWORD size = 0;
		if( RegQueryValueEx( typeKey, "Content Type", 0, &keyType, 0, &size ) || keyType != REG_SZ || !size ) {
			RegCloseKey( typeKey );
			return UNKNOWN_FILE;
		}
		//
		// Now attempt to actually read the data out. 
		//
		std::vector<char> buffer(size + 1);
		std::string type = UNKNOWN_FILE;
		//
		// Type typecast here is nasty, but required because the function
		// call doesn't know that it's returning a signed character type.
		//
		if( !RegQueryValueEx( typeKey, "Content Type", 0, &keyType, (unsigned char*)&(buffer[0]), &size ) )
			type = &(buffer[0]);
		RegCloseKey( typeKey );
		return type;
	}
}
